#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "myjni.h"
#include "platform_config.h"

//水泵不工作时的AD值
#define MIN_WORKING_AD 1500
//水泵慢速喷药时的AD值
#define SLOW_WORKING_AD 1580
//水泵快速喷药时的AD值 
#define FAST_WORKING_AD 1680

//设定PWM个数与对应的升数，升数单位0.1
unsigned int g_setPwmNum = 500;
unsigned int g_setPwmLiters = 10;
//设定水泵时长(秒)与对应的升数，升数单位0.1
unsigned int g_setFastWorkSeconds = 330;//330秒
unsigned int g_setFastWorkLiters = 100;//10.0升
unsigned int g_setSlowWorkSeconds = 520;//520秒
unsigned int g_setSlowWorkLiters = 100;//10.0升
unsigned long int g_sumOfPwm = 0;

static unsigned int g_startGpsPointsNum = 4;
int GPS_POINT_Index1 = 0;
double LengMaxx;
double LengMaxy;
double currentLatitude=0;
double currentLongitude=0;
int CaliAreaFlag=1;//为0实时连续计算面积，为1最终面积计算
int AddPointFlag=0;//为0不加点，为1加点
double BottomMaxy;
double g_tminx;
double g_tminy;
double g_tmaxx;
double g_tmaxy;
u16 g_workSeconds = 0;
u16  g_pesticidesLiter =0;//农药消耗量
u16  g_PercentOfAreaPassed = 0;//亩数合格率
u32 planePointIndex = 0;
double MeterInPerLat = 0;//每1纬度变化，代表多少米
double MeterInperLng = 0;//每1经度变化，代表多少米
stru_GPSPOINT   planePoint[MAX_GPS_POINT];
stru_GPSPOINT   GPS_POINT_Data2[MAX_OUTLINE_POINT];
stru_GPSPOINT gps_point_ref;
u16  g_pesticidesAdBuff[MAX_GPS_POINT];//农药AD值
stru_GPSPOINT g_middlePoint;
u16  g_recordPointsNumber = 0;
u8 g_flagOfStartWork = 0;
u8 g_flagOfStopWork = 0;
u16 g_startIndex = 0;
u16 g_stopIndex = 0;
u32 g_startSeconds = 0;//开始喷药的秒数
u32 g_stopSeconds = 0;//结束喷药的秒数
double g_areaInMu = 0;//轮廓面积
double  g_areaOfTravel = 0;//行进面积
double  g_totalDistance = 0;//累计总距离
u16  g_workingWidth = 500;
static u32 g_gpsPointNum = 0;
static double g_refLatitude = 0;
static double g_refLongitude = 0;
static u8 g_driftingGPSnum = 0;
extern SysInf  SysInfor;
extern u32 g_currentAdValue;
u16 g_emptyCounter = 0;
double g_currentLatitude;
double g_currentLongitude;
double g_currentPesticides;//跟随位置信息一起上传，如果脉冲型，上传脉冲数，如果电压型，上传电压
static double CaliAreaXuanDian(void);
double checkSpraySpeed(void);
static  double roundx(double x) {
	return ((int)(x + 0.5));
}

static double rad(double d) {
    return d * PI / 180.0;
}

/////--------求两点间距离---------/////////////
static double GetDistance(double lat1, double lng1, double lat2, double lng2)
{
    double radLat1 = rad(lat1);
    double radLat2 = rad(lat2);
    double a = radLat1 - radLat2;
    double b = rad(lng1) - rad(lng2);
    double c = 2 * asin(sqrt(pow(sin(a/2),2)+cos(radLat1)*cos(radLat2)*pow(sin(b/2),2)));

    c = c * EARTH_RADIUS;
    c = roundx(c * 1000000)/1000;//千米转换为米，取小数点3位
    return c;
}

static double getBearing(double bearing1, double bearing2) {
    double bearing = abs(bearing1-bearing2);
    if (bearing > 180) {
        bearing = 360 - bearing;
    }
    return bearing;
}

//去除漂移点
u16 removeDriftGpsPoint(double *Latitude, double *Longitude)
{
    u16 distance = 0;

    if (g_gpsPointNum == 1)//第一个点作为参考点
    {
        g_refLatitude = *Latitude;
        g_refLongitude = *Longitude;
    }
    else if (g_gpsPointNum > 2)
    {
        distance = GetDistance(g_refLatitude, g_refLongitude, *Latitude, *Longitude);
        //时速限定,超限视为漂移点，不更新当前经纬度，连续三次出现坏点时，说明参考点是坏点，剔除参考点，同时更新当前经纬度
        if( distance < MAX_GPS_SPEED_MS * g_driftingGPSnum)
        {
            g_refLatitude = *Latitude;
            g_refLongitude = *Longitude;
            g_driftingGPSnum = 0;
        }
        else //距离超限，视为GPS漂移,去除漂移点
        {
            g_driftingGPSnum++;
            if(g_driftingGPSnum >= 3)//连续3个点都超限时，判定参考点为漂移点
            {
                g_refLatitude = *Latitude;
                g_refLongitude = *Longitude;
if(planePointIndex >= 3){
planePointIndex = planePointIndex - 2;
}
            }
            else//当前点为坏点时，不更新当前经纬度
            {
                *Latitude = g_refLatitude;
                *Longitude = g_refLongitude;
            }
            g_gpsPointNum--;
        }
    }
    return distance;

}

//GPS经纬度转换为平面坐标点
void GpsToPlanePoin(double lat,double lng)
{
    //  char temp[20];
    //第一点作为参考点,按键由弹起到按下时，确定参考点

	if (planePointIndex == g_startGpsPointsNum)
	{
		gps_point_ref.x = lat;
		gps_point_ref.y = lng;
		MeterInPerLat = GetDistance(lat, lng, lat + 1, lng);
		MeterInperLng = GetDistance(lat, lng, lat, lng + 1);
		memset(planePoint, 0, sizeof(planePoint));
		memset(GPS_POINT_Data2, 0, sizeof(GPS_POINT_Data2));
	}

    //转换坐标系
    planePoint[planePointIndex].x=(lat-gps_point_ref.x)*MeterInPerLat;
    planePoint[planePointIndex].y=(lng-gps_point_ref.y)*MeterInperLng;

}

//记录点信息，包含GPS坐标，响应的药量AD值,定位后，点数超过3个，先执行去除GPS漂移,接收到一个GPS点，执行一次
void recordPointsMessage(double g_currentLatitude, double g_currentLongitude)
{
    u16 i=0;
    //先进先出，最新的点在队尾
    if(g_recordPointsNumber == MAX_GPS_POINT)
    {
        for(i=1;i<MAX_GPS_POINT-1;i++)
        {
            g_pesticidesAdBuff[i-1] = g_pesticidesAdBuff[i];
            planePoint[i-1].x=planePoint[i].x;
            planePoint[i-1].y=planePoint[i].y;
        }
    }

	GpsToPlanePoin(g_currentLatitude, g_currentLongitude);//将GPS点转换为平面 坐标，并且保存在缓存中
		g_pesticidesAdBuff[planePointIndex] = g_sumOfPwm;//记录当前脉冲数

	g_currentPesticides = g_pesticidesAdBuff[planePointIndex];


    if(++planePointIndex >= MAX_GPS_POINT)//缓存边界处理
    {
        planePointIndex = MAX_GPS_POINT -1 ;    
        g_recordPointsNumber = MAX_GPS_POINT;   
    }
    if(g_recordPointsNumber<MAX_GPS_POINT)
        g_recordPointsNumber++;
}

static inline void MEMSET_U16(u16 *src, u16 val, u32 len) {
    u32 i;
    for (i = 0; i < len; i++)
        src[i] = val;
}

/*
检测开始喷药前，先确定参考液位，参考液位是数组最前面20个数的最大值，并且记录该参考液位在数组中的位置，从该位置向后进行逐个比较，检测药量是否下降，确定是否开始喷药
*/
u16 getReferenceAdValue(u16 *pIndex)
{
	u16 i=0;
	u16 adValue = g_pesticidesAdBuff[3];
	if(g_recordPointsNumber>20)
	{
		for(i=3;i<20;i++)
			{
				if ( adValue < g_pesticidesAdBuff[i])
					 {
					 	adValue = g_pesticidesAdBuff[i];
					 	*pIndex =i;
					}
			}
		
	}
	return adValue;
}

u16 g_ReferenceAdValue = 0;
u16 g_ref_position = 0;

/*
////判断工作状态,
// 脉冲型//脉冲连续n秒连续增加
//电压型:连续工作n秒，判定开始喷药
*/
u8 checkIfStartWork(u16 *pIndex) {
	int i = 0;
	int true_num = 0;
	//if (g_modeOfCalcWater == SPAY_MODE_PWM) {//脉冲型//脉冲连续n秒连续增加
		LOGE("adc**** planePointIndex=%u, g_pesticidesAdBuff[planePointIndex - 1]=%u   ", planePointIndex, g_pesticidesAdBuff[planePointIndex - 1]);
		if (g_pesticidesAdBuff[planePointIndex - 1] > g_pesticidesAdBuff[planePointIndex - 2] &&
			g_pesticidesAdBuff[planePointIndex - 2] > g_pesticidesAdBuff[planePointIndex - 3] &&
			g_pesticidesAdBuff[planePointIndex - 3] > g_pesticidesAdBuff[planePointIndex - 4] &&
			g_pesticidesAdBuff[planePointIndex - 4] > g_pesticidesAdBuff[planePointIndex - 5]) {
			*pIndex = planePointIndex - 4;
			return 1;
		}

	//}
	return 0;
}
/*
////判断工作状态,
// 脉冲型//脉冲连续n秒不增加，视为停止
//电压型:连续不工作n秒，视为停止
*/
u8 checkIfStopWork(u16 *pIndex) {
	int i = 0;
	int true_num = 0;
		if (g_pesticidesAdBuff[planePointIndex - 1] == g_pesticidesAdBuff[planePointIndex - 9]) {
			*pIndex = planePointIndex - 9;
			return 1;
		}

	return 0;
}

long g_secondCounter() {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec;
}
unsigned int g_isMovingCounter = 0;
unsigned int g_isStopCounter = 0;
void AndroidGpsProcess(double Latitude, double Longitude)
{
    long t1, t2;

//电池拔出、不在计算面积与AD值
	if(g_flagOfBatteryPull == 1){
			return;
		}

    t1 = currentTimeInUsec();
    if (g_gpsPointNum < MAX_GPS_POINT)
        g_gpsPointNum++;//gps点数  
    removeDriftGpsPoint(&Latitude, &Longitude);//去除漂移点

	LOGE("gps******纬度:%f		经度:%f		速度:%f     方向:%f     脉冲=%lu", Latitude, Longitude, gps_speed, gps_bearing, g_sumOfPwm);
	g_currentLatitude = Latitude;
	g_currentLongitude = Longitude;

	if (g_gpsPointNum >= g_startGpsPointsNum)//gps点数超过3个开始记录
	{
		recordPointsMessage(Latitude, Longitude);  //记录每个GPS点的对应信息，及相应的液位
		//send_a_num(1,planePointIndex);
		if (g_recordPointsNumber > 20)//记录的点数超过N时, 查找是否开始喷药, 并记录相对应的缓存位置
		{
			if (g_flagOfStartWork == 0)
			{
				if (gps_speed >= 0.5) {
					if (++g_isMovingCounter > 3) {//起飞3秒，视为开始作业
						g_flagOfStartWork = 1;
						g_startIndex = planePointIndex - 1;
							
					}

				}
				else
				{
					g_isMovingCounter = 0;
				}
			//	g_flagOfStartWork = checkIfStartWork(&g_startIndex);
				if (g_flagOfStartWork == 1) //判断开始后，不重复判断
				{
					g_startSeconds = g_secondCounter() + g_startIndex - planePointIndex; //开始的时间需要减去判定延迟时间，否则消耗时间比实际偏小
					LOGE("adc******开始喷药！！！！！！");
					write_log_to_sdcard("adc******开始喷药！");
					LOGE("gps******g_startIndex==%d", g_startIndex);
				}

			}
			else if (g_flagOfStopWork == 0)//开始后，判断结束，不重复判断
			{
				if (planePointIndex > (u32)(g_startIndex + 10)) {
					if (gps_speed < 0.5) {//飞机停止后超过3秒，结算面积
						if (++g_isStopCounter > 3) {
							g_flagOfStopWork = 1;
							g_stopIndex = planePointIndex - 1;
						}

					}
					else
					{
						g_isStopCounter = 0;
					}
				}
					//g_flagOfStopWork = checkIfStopWork(&g_stopIndex);
				if (g_flagOfStopWork == 1)
				{
					g_stopSeconds = g_secondCounter() - 6;
					LOGE("adc******$停止喷药##########");
					write_log_to_sdcard("停止喷药！");
					LOGE("gps******g_stopIndex==%d", g_stopIndex);
				}
			}
		}

    }    

    if(g_flagOfStopWork == 1)
    {    
        CalAreaProcess();
    }
    t2 = currentTimeInUsec();
    //LOGE("%s 耗时:%luus", __func__, t2 - t1);
}


//求2个平面坐标点之间的距离
double GetDistanceInPlant(double x1,double y1,double x2,double y2)
{
    double distance=0;
    distance = fabs( pow((x1-x2), 2) + pow((y1-y2), 2) );
    return sqrt(distance);
}


//计算行进总距离
void getTotalDistance(void)
{
    u16 i;
    double g_neighborGpsDistances;
    //计算单点移动距
    for (i = g_startIndex; i < g_stopIndex; i++)
    {
        g_neighborGpsDistances = GetDistanceInPlant(planePoint[i].x,planePoint[i].y,planePoint[i+1].x,planePoint[i+1].y);
        if(g_neighborGpsDistances < 20)
            g_totalDistance += g_neighborGpsDistances;
    }

}//


//计算面积
void getAreaOfTravel(void)
{
	//g_areaOfTravel = g_totalDistance ;// * g_workingWidth  / 66670.0;//喷洒宽度的单位是厘米，故而需要除以   (666.7*100)
	g_areaOfTravel = g_totalDistance * SysInfor.WORKING_WIDTH / 66670.0;

	LOGE("gps***** g_totalDistance = %f", g_totalDistance);
	LOGE("gps***** g_areaOfTravel =%d ", (u16)(g_areaOfTravel * 100));

    g_totalDistance =0;//行进距离清零

}//




//处理计算作业面积任务
void dealWithWorkingArea(void)
{
    if(planePointIndex>=10)//超过n个点计算距离
    {
        getTotalDistance();
        getAreaOfTravel();
    }
    else
        g_areaOfTravel =0;

}//

/*


//查看喷药速度，1快速，0慢速
*/

double checkSpraySpeed(void) {
	u32 adc_sum = 0;
	u32 adc_average = 0;
	u32 num = 0;
	float spraySpeedMax = (float)g_setFastWorkLiters / g_setFastWorkSeconds;
	float spraySpeedMin = (float)g_setSlowWorkLiters /g_setSlowWorkSeconds;
	float spraySpeed = spraySpeedMin;
	int i = 0;
	for (i = g_startIndex ; i < g_stopIndex; i++) {
	LOGE("adc*****g_pesticidesAdBuff[i]=%u",g_pesticidesAdBuff[i]);
		if (g_pesticidesAdBuff[i] > MIN_WORKING_AD) {
			adc_sum += g_pesticidesAdBuff[i];
			++num;
		}
	}
	adc_average = adc_sum / num;
	LOGE("adc*****adc_sum ===%u,  num=====%u,  adc_avrage=%u",adc_sum,num,adc_average);
	if (adc_average >= FAST_WORKING_AD) {
		return spraySpeedMax;
	}else if(adc_average <= SLOW_WORKING_AD){
		return spraySpeedMin;
	}
	else
	{
		spraySpeed = spraySpeedMin + (spraySpeedMax - spraySpeedMin)*(adc_average - SLOW_WORKING_AD) / (FAST_WORKING_AD - SLOW_WORKING_AD);
	}
	LOGE("adc***** sprayspeed=%f",spraySpeed);
	return spraySpeed;
}


u32 calculataLiquorLiter(u32 value) {
	u32 temp = 0;
	float spraySpeed = 0.0;//喷洒速度，单位：n*0.01L/S

		temp = value * SysInfor.SET_PWM_LITERS /SysInfor.SET_PWM_NUM ;
	
	return temp * 10;
}



void removeNonWorkGps(void)
{
    u16 i;
    for(i=0;i<g_startIndex;i++)
    {
        planePoint[i].x = planePoint[g_startIndex].x ;
        planePoint[i].y = planePoint[g_startIndex].y ;
    }

}


//求出平面坐标系的最值:最大，最小，中心点
void GetMaxPlanePoint(void)
{
    u16 i;
    double p1x;
    double p1y;
    g_tminx = planePoint[0].x;
    g_tminy = planePoint[0].y;
    g_tmaxx = planePoint[0].x;
    g_tmaxy = planePoint[0].y;
    for (i=0; i <planePointIndex ; i++)//循环所有线条求极值
    {
        p1x=planePoint[i].x;
        p1y=planePoint[i].y;

        if(p1x<g_tminx)g_tminx=p1x;//求最小值
        if(p1y<g_tminy)g_tminy=p1y;

        if(p1x>g_tmaxx)g_tmaxx=p1x;//求最大值
        if(p1y>g_tmaxy)g_tmaxy=p1y;
    }
    LengMaxx=(g_tmaxx-g_tminx);
    LengMaxy=(g_tmaxy-g_tminy);
    g_middlePoint.x = (g_tmaxx+g_tminx)/2;
    g_middlePoint.y = (g_tmaxy+g_tminy)/2;
}



//计算亩数合格率
//允许超过100%
u16 CalPercentOfAreaPassed(void)
{
    u16 percent=0;
    if(g_areaInMu > 0.1 && g_areaOfTravel>0.1)
    {   
        percent = g_areaOfTravel*1000/g_areaInMu;
    }   
    return percent;
}






static pthread_mutex_t mutex_area_lock = PTHREAD_MUTEX_INITIALIZER;
void CalAreaProcess() //计算面积处理过程
{
	if (g_flagOfStartWork == 0) {
		write_log_to_sdcard("计算面积, g_flagOfStartWork为0, 返回");
		return;
	}

	pthread_mutex_lock(&mutex_area_lock);
	dealWithWorkingArea();//计算行进面积
	if (g_stopSeconds >= g_startSeconds)
		g_workSeconds = g_stopSeconds - g_startSeconds;//计算用时，单位:秒
	else
		g_workSeconds = g_stopSeconds + 0xffffffff - g_startSeconds;//计算用时，单位:秒
		g_pesticidesLiter = calculataLiquorLiter(g_sumOfPwm);
	


	removeNonWorkGps();//将非工作的GPS点用开始位置的GPS点取代，便于后面计算投影面积
	GetMaxPlanePoint();//取出坐标系中最值
	g_areaInMu = CaliAreaXuanDian();//取边界点并计算面积
	g_PercentOfAreaPassed = CalPercentOfAreaPassed();//计算深松面积合格率
	//print debug message
	LOGE("gps***** g_areaInMu = %f", g_areaInMu);
	LOGE("gps***** g_areaOfTravel = %f", g_areaOfTravel);
	LOGE("gps*adc***** g_pesticidesLiter = %u", g_pesticidesLiter);
	LOGE("gps***** g_workSeconds = %u", g_workSeconds);
	//end
	//  if(g_areaInMu>0.1 && g_areaOfTravel>0.1 && g_pesticidesLiter > (g_areaOfTravel*30) )// 1亩地喷药至少0.6升，如果少于0.3升，不上传
	if (g_areaInMu > 0.1 && g_areaOfTravel > 0.1)
	{
		write_gps_info("gps***** 计算面积数据 面积:%f亩 行进面积:%f亩 药水:%d升 工作时长:%d秒", g_areaInMu, g_areaOfTravel, (u16)g_pesticidesLiter, (u16)g_workSeconds);
		sendAreaData(g_areaInMu * 1000, g_areaOfTravel * 100, (u16)g_pesticidesLiter, (u16)g_workSeconds);//g_pesticidesLiter
		g_startIndex = 0;
		g_stopIndex = 0;
	}
	g_sumOfPwm = 0;
	IOIN1_pwm_sum = 0;
	IOIN2_pwm_sum = 0;
	planePointIndex = 0;
	GPS_POINT_Index1 = 0;
	g_flagOfStopWork = 0;
	g_flagOfStartWork = 0;
	g_recordPointsNumber = 0;
	pthread_mutex_unlock(&mutex_area_lock);
}

//////////-----多边形求面积-----/////////////
/*static double CaliArea(stru_GPSPOINT pPoint[],int index)//多边形求面积
{
    double iArea=0;
    u16 i;
    for ( i=0; i <index; i++)//循环所有线条
    {
        iArea += (pPoint[i].x * pPoint[i+1].y) - (pPoint[i+1].x * pPoint[i].y);
    }
    iArea += (pPoint[index-1].x * pPoint[0].y) - (pPoint[index-1].x * pPoint[0].y);
    return iArea=abs(0.5*iArea);
}*/
static double CaliArea(stru_GPSPOINT pPoint[], int index)//多边形求面积
{
	double iArea = 0;
	unsigned short i;
	iArea = pPoint[0].y * (pPoint[index - 1].x - pPoint[1].x);
	for (i = 1; i < index - 1; ++i)
		iArea += pPoint[i].y * (pPoint[i - 1].x - pPoint[i + 1].x);
	return iArea = abs(0.5*iArea);
}

////----求最高连续点-----/////////////
static double TopMiny;
static void CalTopPiont(u32 count)
{
    double ttmaxy=0;
    double ttmaxx=0;
    u32 i,j,k;
    double dx; 
    k=0;
    dx=LengMaxx/count;
    for(i=0;i<count;i++)//分割后循环
    {   
        ttmaxy=g_middlePoint.y;
        for (j=0; j <planePointIndex-2;j++)//循环所有线条
        {
            if(planePoint[j].x>=(g_tminx+i*dx) && planePoint[j].x <= g_tminx+(i+1)*dx)
            {
                if(ttmaxy<planePoint[j].y)
                {
                    ttmaxy=planePoint[j].y;
                    ttmaxx=planePoint[j].x;
                }
            }    
        }
        if(ttmaxy!=g_middlePoint.y)//添加新点
        {
            GPS_POINT_Data2[GPS_POINT_Index1].x=ttmaxx;
            GPS_POINT_Data2[GPS_POINT_Index1].y=ttmaxy;
            GPS_POINT_Index1++;
            k++;
        }
    }   
    //去掉3点间，中间最低点
    if(k<2)return;
    for(i=2;i<k;i++)
    {   
        if(GPS_POINT_Data2[GPS_POINT_Index1-i].y<GPS_POINT_Data2[GPS_POINT_Index1-i-1].y && GPS_POINT_Data2[GPS_POINT_Index1-i].y<GPS_POINT_Data2[GPS_POINT_Index1-i+1].y)
            GPS_POINT_Data2[GPS_POINT_Index1-i].y=GPS_POINT_Data2[GPS_POINT_Index1-i+1].y;  
    }   
    TopMiny=GPS_POINT_Data2[GPS_POINT_Index1-1].y;
    for(i=1;i<k;i++)//取出上边线，最小的Y值
    {   
        if(TopMiny>GPS_POINT_Data2[GPS_POINT_Index1-i].y)TopMiny=GPS_POINT_Data2[GPS_POINT_Index1-i].y;
    }  
}

//////----求最右边连续点-----/////////
static double RightMinx;
static void CalRightPiont(u32 count)
{
    double ttmaxy=0;
    double ttmaxx=0;
    u32 i,j,k;
    double dy;
    dy=LengMaxy/count;
    k=0;
    for(i=0;i<count;i++)//分割后循环
    {
        ttmaxx=g_middlePoint.x;
        for (j=0; j <planePointIndex-2;j++)//循环所有线条
        {
            if(planePoint[j].y<=(g_tmaxy-i*dy)&&planePoint[j].y>=(g_tmaxy-(i+1)*dy))
            {
                if(ttmaxx<planePoint[j].x)
                {
                    ttmaxy=planePoint[j].y;
                    ttmaxx=planePoint[j].x;
                }
            }
        }
        if(ttmaxx!=g_middlePoint.x)
        {
            GPS_POINT_Data2[GPS_POINT_Index1].x=ttmaxx;
            GPS_POINT_Data2[GPS_POINT_Index1].y=ttmaxy;
            GPS_POINT_Index1++;
            k++;
        }
    }

    //去掉3点间，中间最左点
    if(k<2)return;
    for(i=2;i<k;i++)
    {
        if(GPS_POINT_Data2[GPS_POINT_Index1-i].x<GPS_POINT_Data2[GPS_POINT_Index1-i-1].x
                &&GPS_POINT_Data2[GPS_POINT_Index1-i].x<GPS_POINT_Data2[GPS_POINT_Index1-i+1].x)
            GPS_POINT_Data2[GPS_POINT_Index1-i].x=GPS_POINT_Data2[GPS_POINT_Index1-i+1].x;
    }

    RightMinx=GPS_POINT_Data2[GPS_POINT_Index1-1].x;
    for(i=1;i<k;i++)
    {
        if(RightMinx>GPS_POINT_Data2[GPS_POINT_Index1-i].x)RightMinx=GPS_POINT_Data2[GPS_POINT_Index1-i].x;
    }

}

//////----求最低边连续点-----/////////
static void CalBottomPiont(u32 count)
{
    double tminx,tminy;
    u32 i,j,k;
    double dx;
    k=0;
    tminx=tminy=100000;//100km
    dx=LengMaxx/count;
    for(i=0;i<count;i++)//分割后循环
    {
        tminy=g_middlePoint.y;
        for (j=0; j <planePointIndex-2;j++)//循环所有线条
        {
            if(planePoint[j].x<=(g_tmaxx-i*dx)&&planePoint[j].x>=(g_tmaxx-(i+1)*dx))
            {
                if(tminy>planePoint[j].y)
                {
                    tminy=planePoint[j].y;
                    tminx=planePoint[j].x;
                }
            }
        }
        if(tminy!=g_middlePoint.y)
        {
            GPS_POINT_Data2[GPS_POINT_Index1].x=tminx;
            GPS_POINT_Data2[GPS_POINT_Index1].y=tminy;
            GPS_POINT_Index1++;
            k++;
        }
    }
    //去掉3点间，中间最高点
    if(k<2)return;
    for(i=2;i<k;i++)
    {
        if(GPS_POINT_Data2[GPS_POINT_Index1-i].y>GPS_POINT_Data2[GPS_POINT_Index1-i-1].y &&GPS_POINT_Data2[GPS_POINT_Index1-i].y>GPS_POINT_Data2[GPS_POINT_Index1-i+1].y)
            GPS_POINT_Data2[GPS_POINT_Index1-i].y=GPS_POINT_Data2[GPS_POINT_Index1-i+1].y;
    }

    BottomMaxy=GPS_POINT_Data2[GPS_POINT_Index1-1].y;
    for(i=1;i<k;i++)
    {
        if(BottomMaxy<GPS_POINT_Data2[GPS_POINT_Index1-i].y)
            BottomMaxy=GPS_POINT_Data2[GPS_POINT_Index1-i].y;
    }

}

//////----求最左边连续点-----/////////
static void CalLeftPiont(u32 count)
{
    double tminx,tminy;
    u32 i,j,k;
    double dy;
    k=0;
    tminx=tminy=100000;//100km
    dy=LengMaxy/count;
    for(i=0;i<count;i++)//分割后循环
    {
        tminx=g_middlePoint.x;
        for (j=0; j <planePointIndex-2;j++)//循环所有线条
        {
            if(planePoint[j].y>=(g_tminy+i*dy)&&planePoint[j].y<=(g_tminy+(i+1)*dy))
            {

                if(tminx>planePoint[j].x)
                {
                    tminy=planePoint[j].y;
                    tminx=planePoint[j].x;
                }
            }
        }
        if(tminx!=g_middlePoint.x)
        {
            GPS_POINT_Data2[GPS_POINT_Index1].x=tminx;
            GPS_POINT_Data2[GPS_POINT_Index1].y=tminy;
            GPS_POINT_Index1++;
            k++;
        }
    }
    if(k<2)return;
    //去掉3点间，中间最右点
    for(i=2;i<k;i++)
    {
        if(GPS_POINT_Data2[GPS_POINT_Index1-i].x>GPS_POINT_Data2[GPS_POINT_Index1-i-1].x &&GPS_POINT_Data2[GPS_POINT_Index1-i].x>GPS_POINT_Data2[GPS_POINT_Index1-i+1].x)
            GPS_POINT_Data2[GPS_POINT_Index1-i].x=GPS_POINT_Data2[GPS_POINT_Index1-i+1].x;
    }
}


//得到因GPS天线安装位置偏差带来的面积误差
/*double GetOffsetAreaForAntennaPosition(void)
{
    u16 i=0;
    double x1;
    double x2;
    double y1;
    double y2;
    double area=0;
    double QuYangLength =0;

    for(i=0;i<GPS_POINT_Index1;i++)
    {
        x1=GPS_POINT_Data2[i].x;
        x2=GPS_POINT_Data2[i+1].x;
        y1=GPS_POINT_Data2[i].y;
        y2=GPS_POINT_Data2[i+1].y;
        QuYangLength+=sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
    }
    area =SysInfor.WORKING_WIDTH*QuYangLength/200;
    //area =g_workingWidth*QuYangLength/200;
    return area;
}*/
double GetOffsetAreaForAntennaPosition(void)
{
	unsigned short i = 0;
	double x1;
	double x2;
	double y1;
	double y2;
	double area = 0;
	double QuYangLength = 0;

	for (i = 0; i < GPS_POINT_Index1 - 1; i++)
	{
		x1 = GPS_POINT_Data2[i].x;
		x2 = GPS_POINT_Data2[i + 1].x;
		y1 = GPS_POINT_Data2[i].y;
		y2 = GPS_POINT_Data2[i + 1].y;
		QuYangLength += sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1));
	}
	area = SysInfor.WORKING_WIDTH * QuYangLength / 200;
	return area;
}

//////////----取边界点后求面积---///////////
static double CaliAreaXuanDian(void)
{
    double iArea=0;
    u16 count=6;//分步数
    u16 slen=SysInfor.WORKING_WIDTH / 100;
    u16 t;
    if(planePointIndex<20)return 0;
    /////////----求最高连续点-----/////////////////////
    memset(GPS_POINT_Data2,0,sizeof(GPS_POINT_Data2));
    GPS_POINT_Index1 =0;
    if(count<LengMaxx/slen)
        t=(u32)(LengMaxx/slen);                                                                                                                                                                          
    else
        t=count;
    CalTopPiont(t);
    /////////----求最右边连续点-----/////////////////////
    if(count<LengMaxy/slen)t=(int)(LengMaxy/slen);else t=count;
    CalRightPiont(t);
    /////////----求最低连续点-----/////////////////////
    if(count<LengMaxx/slen)t=(int)(LengMaxx/slen);else t=count;
    CalBottomPiont(t);
    /////////----求最左边连续点-----/////////////////////
    if(count<LengMaxy/slen)t=(int)(LengMaxy/slen);else t=count;
    CalLeftPiont(t);
    iArea=CaliArea(GPS_POINT_Data2,GPS_POINT_Index1);//求面积


    iArea+=GetOffsetAreaForAntennaPosition();

    CaliAreaFlag=1;
    return (iArea/666.67);

}
